import React, {Component} from 'react'
import {connect} from 'react-redux';
import {Add, Undo, Redo} from './store/Actions/TravelActions';

class ReduxTravel extends Component {
    constructor(props) {
        super(props);
        this.inputRef = React.createRef();

        /**
         * 记录Redux中的currentIndex；因为_addListItem会触发Redux中的currentIndex的变化因而调用componentWillReceiveProps。本身_addListItem已经有setState，
         * 不需要在set一次了，防止二次渲染；所以这里的作用的是判断组件记录的currentIndex与Redux中的currentIndex是否相同，如果相同说明是_addListItem触发的
         * componentWillReceiveProps方法的调用；如果不同说明是Undo或者Redo触发的componentWillReceiveProps方法的调用；
         * @type {*|number}
         */
        this.currentIndex = props.currentIndex;
        this.state = {

            /**
             * 默认情况下，保存每次状态的数组为空数组且首次渲染时候因为currentIndex为-1，所以props.list[props.currentIndex]会为undefined。
             * 所以在没有数据的情况下组件的current状态置为空数组防止出错
             */
            current: props.list[props.currentIndex] || []//
        };
    }

    componentWillReceiveProps(nextProps) {
        let currentIndex = nextProps.currentIndex;
        if (currentIndex !== this.currentIndex) {
            let currentState = this.props.list[currentIndex];
            this.setState({
                current: currentState
            }, () => {
                this.currentIndex = currentIndex;
            })
        }
    }

    componentDidMount() {
        this.inputRef.current.focus();

        //初始化Redux中存储状态的数组
        this.props.Add(this.state.current);
        //同时给组件的currentIndex属性加1，因为Redux中存储状态的数组已经存储了一个当前状态的数组
        this.currentIndex += 1;
    }

    _addListItem = () => {
        let currentInputContent = this.inputRef.current.value;
        let currentCopy = this.state.current.slice();

        if (currentInputContent) {
            currentCopy.push(currentInputContent);

            this.setState({
                current: currentCopy
            }, () => {
                this.props.Add(currentCopy);
                this.currentIndex += 1;
            })
        }
    };


    _undo = () => {
        const previousIndex = this.props.currentIndex - 1;
        let previousState;
        if (previousIndex > -1) { //防止越界
            previousState = this.props.list[previousIndex];
            this.setState({
                current: previousState
            }, () => {
                this.props.Undo();
            })
        }
    };

    _redo = () => {
        const nextIndex = this.props.currentIndex + 1;
        let nextState;
        if (nextIndex < this.props.list.length) { //防止越界
            nextState = this.props.list[nextIndex];
            this.setState({
                current: nextState
            }, () => {
                this.props.Redo();
            })
        }
    };

    render() {
        const list = this.state.current.map(function (item) {
            return <li key={Math.random()}>{item}</li>
        });
        return (
            <div>
                <MyInput ref={this.inputRef}/>
                <button onClick={this._addListItem}>Add</button>
                <ul style={{'listStyle': 'none'}}>{list}</ul>
                <button onClick={this._undo}>Undo</button>
                <button onClick={this._redo}>Redo</button>
            </div>
        )
    }
}

const MyInput = React.forwardRef((props, ref) => <TextInput refs={ref}/>);

class TextInput extends Component {
    render() {
        return (
            <input type="text" ref={this.props.refs}/>
        )
    }
}


const mapStateToProps = ({travel}) => {
    return {
        list: travel.list || [],
        currentIndex: travel.currentIndex || 0
    }
};

const mapDispatchToProps = {
    Add, Undo, Redo
};


export default connect(mapStateToProps, mapDispatchToProps)(ReduxTravel);